/*****************************************************************************

                 ,//////,   ,////    ,///' /////,
                ///' ./// ///'///  ///,    ,, //
               ///////,  ///,///   '/// //;''//,
             ,///' '///,'/////',/////'  /////'/;,

    Copyright 2010 Marcus Jansson <mjansson256@yahoo.se>

    This file is part of ROSA - Realtime Operating System for AVR32.

    ROSA is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    ROSA is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with ROSA.  If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
/* Tab size: 4 */

struct tcb_record_t;

#ifndef rosa_def_H_
#define rosa_def_H_

#include "rosa_config.h"
#include "kernel/rosa_semaphore_internal.h"

/***********************************************************
 * TCB block
 *
 * Comment:
 * 	This struct contain all the necessary information to
 * 	do a context switch
 *
 **********************************************************/
typedef enum {Ready, Running, Waiting, Blocked, Terminated} TaskState;
typedef enum {SOS_InfiniteWait, SOS_FiniteWait, SOS_GotSemaphore, SOS_Timeout} SemaphoreOperationStatus;

/// Extra safety margin for stack - 16 bytes
#define STACK_MARGIN 16

typedef struct tcb_record_t {
	struct tcb_record_t * nexttcb;
	char id[NAMESIZE];		//The task id/name
	void (*staddr) (void);	//Start address
	unsigned char *dataarea;			//The stack data area
	int datasize;			//The stack size
	unsigned char *saveusp;			//The current stack position
	int SAVER0;				//Temporary work register
	int SAVER1;				//Temporary work register
	int savesr;				//The current status register
	int retaddr;			//The return address
	int savereg[15];		//The CPU registers
	unsigned int priority;			//priority of the task
	unsigned int dynamicPriority;	//dynamic priority of the task
	long wakeUpTime;		//Time when the task wants to wake up, in systicks
	SemaphoreImpl *lockedSemaphoresListHead;	// Linked list of all IPCP semaphores locked by task
	TaskState state;		//Scheduling state of the task
	struct tcb_record_t *nextInBlockList;	// Linked list of all tasks that are blocked on a particular semaphore
	SemaphoreImpl *semaphoreThatWereWaitingFor;	// When the task is blocked on a semaphore, this pointer points to the semaphore.
	SemaphoreOperationStatus semStatus;		// Result of the pending semaphore operation
} tcb;

/// Dynamically allocates memory for a new task
tcb *allocateTask(unsigned int stackSize);

/// Frees the memory associated with a task
void freeTask(tcb *task);

#endif /* rosa_def_H_ */
